package fr.vahren.dotastrat.model;

import java.util.ArrayList;
import java.util.List;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import fr.vahren.dotastrat.game.D2SGameState;
import fr.vahren.dotastrat.game.effect.D2SEffect;

public class D2SZone {

	private List<D2SHeroUnit> units = new ArrayList<>();

	private List<D2SWards> wards = new ArrayList<>();

	private List<D2SCreeps> creeps = new ArrayList<>();

	private List<D2SEffect> effects = new ArrayList<>();

	private int id;

	private D2SCreepType creepType1;

	private D2SCreepType creepType2;

	private D2SShop shop;

	private List<D2STower> towers = new ArrayList<>();

	private D2SBarracks rangedBarracks;
	private D2SBarracks meleeBarracks;

	public D2SZone(int id, D2SCreepType creepType1, D2SCreepType creepType2,
			List<D2STower> towers, D2SBarracks rangedBarracks,
			D2SBarracks meleeBarracks, D2SShop shop) {
		this.id = id;
		this.creepType1 = creepType1;
		this.creepType2 = creepType2;
		if (towers != null) {
			this.towers.addAll(towers);
		}
		this.rangedBarracks = rangedBarracks;
		this.meleeBarracks = meleeBarracks;
		this.shop = shop;
	}

	/**
	 * @return the units
	 */
	public List<D2SHeroUnit> getUnits() {
		return units;
	}

	/**
	 * @param units
	 *            the units to set
	 */
	public void setUnits(List<D2SHeroUnit> units) {
		this.units = units;
	}

	/**
	 * @return the wards
	 */
	public List<D2SWards> getWards() {
		return wards;
	}

	/**
	 * @param wards
	 *            the wards to set
	 */
	public void setWards(List<D2SWards> wards) {
		this.wards = wards;
	}

	/**
	 * @return the creeps
	 */
	public List<D2SCreeps> getCreeps() {
		return creeps;
	}

	/**
	 * @param creeps
	 *            the creeps to set
	 */
	public void setCreeps(List<D2SCreeps> creeps) {
		this.creeps = creeps;
	}

	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return the creepType1
	 */
	public D2SCreepType getCreepType1() {
		return creepType1;
	}

	/**
	 * @param creepType1
	 *            the creepType1 to set
	 */
	public void setCreepType1(D2SCreepType creepType1) {
		this.creepType1 = creepType1;
	}

	/**
	 * @return the creepType2
	 */
	public D2SCreepType getCreepType2() {
		return creepType2;
	}

	/**
	 * @param creepType2
	 *            the creepType2 to set
	 */
	public void setCreepType2(D2SCreepType creepType2) {
		this.creepType2 = creepType2;
	}

	/**
	 * @return the towers
	 */
	public List<D2STower> getTowers() {
		return towers;
	}

	/**
	 * @param towers
	 *            the towers to set
	 */
	public void setTowers(List<D2STower> towers) {
		this.towers = towers;
	}

	/**
	 * @return the rangedBarracks
	 */
	public D2SBarracks getRangedBarracks() {
		return rangedBarracks;
	}

	/**
	 * @param rangedBarracks
	 *            the rangedBarracks to set
	 */
	public void setRangedBarracks(D2SBarracks rangedBarracks) {
		this.rangedBarracks = rangedBarracks;
	}

	/**
	 * @return the meleeBarracks
	 */
	public D2SBarracks getMeleeBarracks() {
		return meleeBarracks;
	}

	/**
	 * @param meleeBarracks
	 *            the meleeBarracks to set
	 */
	public void setMeleeBarracks(D2SBarracks meleeBarracks) {
		this.meleeBarracks = meleeBarracks;
	}

	@SuppressWarnings("unchecked")
	public JSONObject generateInfo(D2SGameState phase) {
		JSONObject zone = new JSONObject();
		zone.put("id", id);

		JSONArray units = new JSONArray();
		for (D2SHeroUnit unit : this.units) {
			units.add(unit.getId());
		}
		zone.put("units", units);

		JSONArray buildings = new JSONArray();
		for (D2STower tower : towers) {
			buildings.add(tower.generateInfo(phase));
		}
		if (rangedBarracks != null) {
			buildings.add(rangedBarracks.generateInfo(phase));
		}
		if (meleeBarracks != null) {
			buildings.add(meleeBarracks.generateInfo(phase));
		}
		zone.put("buildings", buildings);

		JSONArray wards = new JSONArray();
		for (D2SWards ward : this.wards) {
			wards.add(ward.generateInfo());
		}
		zone.put("wards", wards);

		JSONArray creeps = new JSONArray();
		for (D2SCreeps creep : this.creeps) {
			creeps.add(creep.generateInfo(phase));
		}
		zone.put("creeps", creeps);

		JSONArray activeAbilities = new JSONArray();
		for (D2SEffect effect : this.effects) {
			activeAbilities.add(effect.generateInfo());
		}
		zone.put("effects", activeAbilities);
		return zone;
	}

	public void putUnit(D2SHeroUnit unit) {
		units.add(unit);
	}

	/**
	 * @return the shop
	 */
	public D2SShop getShop() {
		return shop;
	}

	/**
	 * @param shop
	 *            the shop to set
	 */
	public void setShop(D2SShop shop) {
		this.shop = shop;
	}

	public D2SHeroUnit removeUnit(D2SHeroUnit unit) {
		for (int i = 0; i < units.size(); i++) {
			if (units.get(i).getId() == unit.getId()) {
				return units.remove(i);
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "D2SZone [units=" + units + ", wards=" + wards + ", creeps="
				+ creeps + ", id=" + id + ", creepType1=" + creepType1
				+ ", creepType2=" + creepType2 + ", shop=" + shop + ", towers="
				+ towers + ", rangedBarracks=" + rangedBarracks
				+ ", meleeBarracks=" + meleeBarracks + "]";
	}

	public void removeEffect(D2SEffect effect) {
		effects.remove(effect);
	}

	/**
	 * @return the effects
	 */
	public List<D2SEffect> getEffects() {
		return effects;
	}

	/**
	 * @param effects
	 *            the effects to set
	 */
	public void setEffects(List<D2SEffect> effects) {
		this.effects = effects;
	}

	public void removeTower(D2STower tower) {
		towers.remove(tower);
	}

	public void removeCreep(D2SCreeps creep) {
		creeps.remove(creep);
	}

	public void putCreep(D2SCreeps d2sCreeps) {
		creeps.add(d2sCreeps);
	}

	public boolean hasEnemyUnits(D2SSide side) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean hasEnemyCreeps(D2SSide side) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean hasEnemyBuilding(D2SSide side) {
		// TODO Auto-generated method stub
		return false;
	}

}
